home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Appls / dpv / dpvoutput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-14  |  5.8 KB  |  240 lines  |  [TEXT/????]

  1. /* dpv -- ditroff previewer.  Output functions. */
  2.  
  3. #include "dpv.h"
  4. #include "dpvmachine.h"
  5. #include "dpvoutput.h"
  6.  
  7. WINDOW    *win;            /* output window */
  8.  
  9. /* Scale factors (must be longs to avoid overflow) */
  10.  
  11. long    hscale, hdiv;        /* Horizontal scaling factors */
  12. long    vscale, vdiv;        /* Vertical scaling factors */
  13.  
  14. int paperwidth, paperheight;    /* Paper dimenmsions */
  15.  
  16. /* Variables used to make put1(c) as fast as possible */
  17.  
  18. int    topdraw, botdraw;    /* Top, bottom of rect to redraw */
  19. int    baseline;        /* Caches wbaseline() */
  20. int    lineheight;        /* Caches wlineheight() */
  21. int    doit;            /* Set if output makes sense */
  22. int    vwindow;        /* Caches VWINDOW - baseline */
  23.  
  24. extern void    drawproc();    /* Draw procedore, in dpvcontrol.c */
  25.  
  26. /* Create the window */
  27.  
  28. initoutput(filename)
  29.     char *filename;
  30. {
  31.     int winwidth, winheight;
  32.     int hmargin, vmargin;
  33.     
  34.     setscale();
  35.     wsetdefwinsize(paperwidth, paperheight);
  36.     win= wopen(filename, drawproc);
  37.     wsetdocsize(win, paperwidth, paperheight);
  38.     wsetwincursor(win, wfetchcursor("arrow"));
  39.     
  40.     /* Center the window in the document */
  41.     wgetwinsize(win, &winwidth, &winheight);
  42.     hmargin = (paperwidth - winwidth) / 2;
  43.     if (hmargin < 0)
  44.         hmargin = 0;
  45.     vmargin = (paperheight - winheight) / 2;
  46.     if (vmargin < 0)
  47.         vmargin = 0;
  48.     wshow(win, hmargin, vmargin,
  49.                 paperwidth - hmargin, paperheight - hmargin);
  50. }
  51.  
  52. /* Compute scale factors from screen dimensions and device resolution.
  53.    Call before outputting anything, but after input device resolution
  54.    is known. */
  55.  
  56. static
  57. setscale()
  58. {
  59.     int scrwidth, scrheight, mmwidth, mmheight;
  60.     int hdpi, vdpi;
  61.     
  62.     wgetscrsize(&scrwidth, &scrheight);
  63.     wgetscrmm(&mmwidth, &mmheight);
  64.     hdpi = scrwidth * 254L / 10 / mmwidth;
  65.     vdpi = scrheight * 254L / 10 / mmwidth;
  66.     if (dbg) {
  67.         printf("screen %dx%d pixels, %dx%d mm.\n",
  68.             scrwidth, scrheight, mmwidth, mmheight);
  69.         printf("dots per inch %dx%d\n", hdpi, vdpi);
  70.     }
  71.     /* Adjust mm sizes to 75x75 dpi if a resolution less than 75 dpi
  72.        is reported (some servers lie!) */
  73.     if (hdpi < 75) {
  74.         fprintf(stderr,
  75.             "Adjusting horizontal resolution to 75 dpi\n");
  76.         mmwidth = scrwidth * 254L / 750;
  77.     }
  78.     if (vdpi < 75) {
  79.         fprintf(stderr,
  80.             "dpv: Adjusting vertical resolution to 75 dpi\n");
  81.         mmheight = scrheight * 254L / 750;
  82.     }
  83.     /* Dots/mm == scrwidth/mmwidth, etc.; there are 25.4 mm/inch */
  84.     hscale= 254L * scrwidth / 10;
  85.     hdiv= mmwidth * res;
  86.     vscale= 254L * scrheight / 10;
  87.     vdiv= mmheight * res;
  88.     /* Set desired width & height of paper */
  89.     paperwidth= 210 * scrwidth / mmwidth;
  90.     paperheight= 297 * scrheight / mmheight;
  91.     if (dbg) {
  92.         printf("hscale=%d, hdiv=%d, vscale=%d, vdiv=%d\n",
  93.             hscale, hdiv, vscale, vdiv);
  94.         printf("paper %dx%d\n", paperwidth, paperheight);
  95.     }
  96. }
  97.  
  98. /* Force a redraw event for the entire window.
  99.    Used after a new page is made current. */
  100.  
  101. changeall()
  102. {
  103.     wchange(win, 0, 0, paperwidth, paperheight);
  104. }
  105.  
  106. /* Recompute doit & vwindow.
  107.    Call after each font change and each vertical move.
  108.    Assumes topdraw and botdraw are set by drawproc(),
  109.    and lineheight and baseline are set by usefont(). */
  110.  
  111. recheck()
  112. {
  113.     if (ipage != showpage)
  114.         doit= FALSE;
  115.     else {
  116.         vwindow= VWINDOW - baseline;
  117.         doit= vwindow < botdraw && vwindow+lineheight > topdraw;
  118.     }
  119. }
  120.  
  121. /* Output a funny character, called in response to 'Cxx' input.
  122.    Don't rely on 'doit'; the character might be in a different font,
  123.    invalidating the clipping computations in recheck(). */
  124.  
  125. put1s(s)
  126.     char *s;
  127. {
  128.     if (ipage == showpage)
  129.         drawfunny(s);
  130. }
  131.  
  132. /* Line drawing functions.
  133.    There really do some of the work that belongs in dpvmachine.c,
  134.    and even dpvparse.c. */
  135.  
  136. drawline(dh, dv)
  137.     int dh, dv;
  138. {
  139.     if (ipage == showpage)
  140.         wdrawline(HWINDOW, VWINDOW, HWIN(hpos+dh), VWIN(vpos+dv));
  141.     hpos += dh;
  142.     vpos += dv;
  143. }
  144.  
  145. drawcirc(diameter)
  146.     int diameter;
  147. {
  148.     if (ipage == showpage)
  149.         wdrawcircle(HWIN(hpos+diameter/2), VWINDOW,
  150.             (int)(diameter/2*hscale/hdiv));
  151.     /* I assume hpos, vpos remain unchanged here */
  152. }
  153.  
  154. drawellip(haxis, vaxis)
  155.     int haxis, vaxis;
  156. {
  157.     if (ipage == showpage) {
  158.         wdrawelarc(HWIN(hpos+haxis/2), VWIN(vpos),
  159.             (int) (haxis*hscale/hdiv/2),
  160.             (int) (vaxis*vscale/vdiv/2),
  161.             0, 360);
  162.     }
  163. }
  164.  
  165. #define PI 3.1415726
  166.  
  167. drawarc(n, m, n1, m1)
  168. /*    current position is start of arc
  169.  *    n,m is position of center relative to current
  170.  *    n1,m1 is intersection point of tangents at start- and endpoints
  171.  *    of the arc
  172.  */
  173. {
  174.     double rad, angle1, angle2, sqrt(), atan2(), c;
  175.     int iang1, iang2;
  176.     
  177.     c = 180.0/PI;
  178.     rad = sqrt((double)((n*n)+(m*m)));
  179.     angle1 = c*atan2((double)m,(double)-n);
  180.     angle2 = -2 * (angle1 + c * atan2((double)(m1-m),(double)(n1-n)));
  181.     iang1 = (int) (angle1 + 0.5);
  182.     iang2 = (int) (angle2 + 0.5);
  183.     while (iang1 < 0) iang1 += 360;
  184.     while (iang2 < 0) iang2 += 360;
  185.     while (iang1 >= 360) iang1 -= 360;
  186.     while (iang2 >= 360) iang2 -= 360;
  187.     /* params for wdrawelarc are
  188.      *    x,y for center,
  189.      *    horizontal and vertical radii (different for ellipses)
  190.      *    start angle in degrees and number of degrees to draw.
  191.      *    angles measured anticlockwise from positive x-axis
  192.      */
  193.     if (ipage == showpage)
  194.         wdrawelarc(HWIN(hpos+n), VWIN(vpos+m),
  195.             (int)(rad*hscale/hdiv), (int)(rad*vscale/vdiv),
  196.             iang1, iang2);
  197. }
  198.  
  199. drawwig(buf, fp, flag)
  200.     char *buf;
  201.     FILE *fp;
  202. {
  203.     int dh, dv, x = hpos, y = vpos;
  204.  
  205.     while (getint(&buf, &dh) && getint(&buf, &dv))
  206.         if (ipage == showpage) {
  207.             /* HIRO: should always do this (for side effects)? */
  208.             drawline(x + dh/4 - hpos, y + dv/4 - vpos);
  209.             drawline(dh / 2, dv / 2);
  210.             x += dh;
  211.             y += dv;
  212.         }
  213.     drawline(dh / 4, dv / 4);
  214.     if (strchr(buf, EOL) == NULL) {
  215.         int c;
  216.         /* HIRO: don't know how to do handle this */
  217.         error(WARNING, "rest of very long wiggly line ignored");
  218.         do {
  219.             c = getc(fp);
  220.         } while (c != EOL && c != EOF);
  221.     }
  222. }
  223.  
  224. static bool
  225. getint(pbuf, px)
  226.     char **pbuf;
  227.     int *px;
  228. {
  229.     char *buf= *pbuf;
  230.     while (*buf != EOS && isspace(*buf))
  231.         ++buf;
  232.     if (*buf == EOS || *buf != '-' && !isdigit(*buf))
  233.         return FALSE;
  234.     *px= atoi(buf);
  235.     while (*buf != EOS && !isspace(*buf))
  236.         ++buf;
  237.     *pbuf= buf;
  238.     return TRUE;
  239. }
  240.